// <copyright file="BaseChart.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Globalization;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using YUIAspNet.Common;

[assembly: WebResource("YUIAspNet.Chart.BaseChart.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.Chart.charts.swf", "application/x-shockwave-flash")]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.Chart.expressinstall.swf", "application/x-shockwave-flash")]
namespace YUIAspNet
{
    /// <summary>
    /// Base class for all charts.
    /// </summary>
    [NotThemable]
    public abstract class BaseChart : YUIScriptBaseControl, INamingContainer
    {
        Panel _pnlChartContainer;

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseChart"/> class.
        /// </summary>
        protected BaseChart()
        {
            this.Init += new EventHandler(Chart_Init);
            this.Load += new EventHandler(Chart_Load);
            this.PreRender += new EventHandler(Chart_PreRender);

        }

        void Chart_Init(object sender, EventArgs e)
        {
            _pnlChartContainer = new Panel();
            _pnlChartContainer.ID = "chartContainer";
            this.Controls.Add(_pnlChartContainer);
        }

        void Chart_Load(object sender, EventArgs e)
        {
            ControlKey = "Chart";//we use the same references for all types of charts
        }

        void Chart_PreRender(object sender, EventArgs e)
        {
            _pnlChartContainer.Height = this.Height;
            _pnlChartContainer.Width = this.Width;
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            //no stylesheets here... 
        }

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// Must be overriden in parent control to add client initialization properties and events.
        /// </summary>
        protected override void RegisterClientInitialization()
        {
            AddProperty("ChartContainer", _pnlChartContainer.ClientID);
            if (SWFUrl != null)
                AddProperty("SWFUrl", SWFUrl);

            if (Source == null)
                throw new ArgumentException("Source property cannot be null!");
            AddProperty("Source", Source.Serialize(), true);

            if (this.ChartStyle != null)
                AddProperty("Style", Serialize(ChartStyle), true);

            if (PollingInterval > 0)
                AddProperty("Polling", PollingInterval);

            if (!string.IsNullOrEmpty(OnClientShowTooltip))
                AddEvent("OnShowTooltip", OnClientShowTooltip);
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// Must be overriden in parent control to add depeding scripts.
        /// </summary>
        protected override void RegisterScriptReferences()
        {
            AddScriptReference(new ScriptReference("YUIAspNet.Chart.BaseChart.js", this.GetType().Assembly.FullName));
        }

        private static StringBuilder Serialize(ChartStyle chartStyle)
        {
            StringBuilder sb = new StringBuilder("{");

            if (chartStyle.Padding > 0)
                sb.AppendFormat(CultureInfo.InvariantCulture, YUIJavascriptSerializer.SerializeProperty("padding", chartStyle.Padding));

            if (chartStyle.Font != null)
                sb.AppendFormat(CultureInfo.InvariantCulture, "{0}font: {1}", sb.Length > 1 ? "," : "", SerializeFont(chartStyle.Font));
            if (chartStyle.Legend != null)
                sb.AppendFormat(CultureInfo.InvariantCulture, "{0}legend: {1}", sb.Length > 1 ? "," : "", SerializeLegend(chartStyle.Legend));
            if (chartStyle.TooltipStyle != null)
                sb.AppendFormat(CultureInfo.InvariantCulture, "{0}dataTip: {1}", sb.Length > 1 ? "," : "", SerializeTooltipStyle(chartStyle.TooltipStyle));
            if (chartStyle.Border != null)
                sb.AppendFormat(CultureInfo.InvariantCulture, "{0}border: {1}", sb.Length > 1 ? "," : "", SerializeBorder(chartStyle.Border));
            return sb.Append("}");
        }

        private static StringBuilder SerializeTooltipStyle(TooltipStyle tooltipStyle)
        {
            StringBuilder sbTooltip = new StringBuilder("{");

            sbTooltip.Append(YUIJavascriptSerializer.SerializeProperty("color", tooltipStyle.Color));

            if (tooltipStyle.Border != null)
                sbTooltip.Append(", border: ").Append(SerializeBorder(tooltipStyle.Border));
            if (tooltipStyle.Font != null)
                sbTooltip.Append(",font: ").Append(SerializeFont(tooltipStyle.Font));

            return sbTooltip.Append("}");
        }

        private static StringBuilder SerializeBorder(ChartBorder chartBorder)
        {
            StringBuilder sbBorder = new StringBuilder("{");

            sbBorder.Append(YUIJavascriptSerializer.SerializeProperty("color", chartBorder.Color));
            
            if (chartBorder.Size > 0)
            
                sbBorder.Append(",").Append(YUIJavascriptSerializer.SerializeProperty("size", chartBorder.Size));

            return sbBorder.Append("}");
        }

        private static StringBuilder SerializeFont(ChartFont chartFont)
        {
            StringBuilder sbFont = new StringBuilder("{");

            sbFont.Append(YUIJavascriptSerializer.SerializeProperty("color", chartFont.Color));

            if (!string.IsNullOrEmpty(chartFont.Name))
                sbFont.Append(",").Append(YUIJavascriptSerializer.SerializeProperty("name", chartFont.Name));

            if (chartFont.Size > 0)
                sbFont.Append(",").Append(YUIJavascriptSerializer.SerializeProperty("size", chartFont.Size));

            return sbFont.Append("}");
        }

        private static StringBuilder SerializeLegend(ChartLegend chartLegend)
        {
            StringBuilder sbLegend = new StringBuilder("{");

            sbLegend.Append(YUIJavascriptSerializer.SerializeProperty("display", chartLegend.Display.ToString().ToLowerInvariant()));
            if (chartLegend.Padding > 0)
                sbLegend.Append(",").Append(YUIJavascriptSerializer.SerializeProperty("padding", chartLegend.Padding));
            if (chartLegend.Spacing > 0)
                sbLegend.Append(",").Append(YUIJavascriptSerializer.SerializeProperty("spacing", chartLegend.Spacing));

            if (chartLegend.Font != null)
                sbLegend.Append(", font: ").Append(SerializeFont(chartLegend.Font));

            return sbLegend.Append("}");
        }

        /// <summary>
        /// Gets or sets the source of the chart.
        /// </summary>
        /// <value>The source.</value>
        public DataSourceBase Source { get; set; }

        /// <summary>
        /// Gets or sets the SWF URL for the Charts widget.
        /// </summary>
        /// <value>The SWF URL.</value>
        public Uri SWFUrl { get; set; }

        /// <summary>
        /// Gets or sets the chart style.
        /// </summary>
        /// <value>The chart style.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ChartStyle ChartStyle { get; set; }

        /// <summary>
        /// Gets or sets the polling interval.
        /// </summary>
        /// <value>The polling interval.</value>
        public int PollingInterval { get; set; }

        /// <summary>
        /// Gets or sets the on client show tooltip.
        /// </summary>
        /// <value>The on client show tooltip.</value>
        public string OnClientShowTooltip { get; set; }

        //public override string ThemeName 
        //{
        //    get { throw new ThemesUnsupportedException(); }
        //    set { throw new ThemesUnsupportedException(); }
        //}
    }
}
